#include "XrdDownloadManagerLog.hh"

XrdDownloadManagerLog::XrdDownloadManagerLog ( int debug ) {
    kStdErr = stderr;
//     fLastRotated = 0;
    fDebug = debug;
    fLogFile = NULL;
    SetStdErr();
}

XrdDownloadManagerLog::~XrdDownloadManagerLog() {
    if ( ( fLogFile ) && ( fLogFile != kStdErr ) ) {
        fclose ( fLogFile );
    }
}

void XrdDownloadManagerLog::Init ( bool debug ) {
    if ( !gLogDM ) {
        gLogDM = new XrdDownloadManagerLog ( debug );
    } else {
        gLogDM->Warning ( "Log facility already initialized!" );
    }
}

void XrdDownloadManagerLog::Delete() {
    if ( gLogDM ) {
        delete gLogDM;
    }
}

bool XrdDownloadManagerLog::SetFile ( const char *fn ) {

    // Close previously opened file, if one
    if ( ( fLogFile ) && ( fLogFile != kStdErr ) ) {
        fclose ( fLogFile );
    }
    fLogFile = fopen ( fn, "a" );
    if ( !fLogFile ) {
        SetStdErr();
        return false;
    }

    fLogFileName = fn;

//     time ( &fLastRotated );
//     fRotateable = false;
    return true;
}

void XrdDownloadManagerLog::SetStdErr() {
    if ( ( fLogFile ) && ( fLogFile != kStdErr ) ) {
        fclose ( fLogFile );
    }
    fLogFile = kStdErr;
    fLogFileName = "";
    fRotateable = false;
}

// Return values:
//   0 : not rotated
int XrdDownloadManagerLog::CheckRotate() {
    return 0;
}

void XrdDownloadManagerLog::PrintBanner() {
    if ( !fBanner.empty() ) {
        Info ( "%s",fBanner.c_str() );
    }
}

void XrdDownloadManagerLog::CheckRotateAndFormat ( MsgType_t type, const char *fmt, va_list args ,int debug, ...) {

    // Messages are not eventually mangled by several threads trying to write,
    // and in the worst case, even rotate the log file, at the same time
//   TThread::Lock();

    int r = CheckRotate();
    va_list vl1;
    va_start(vl1, debug);
    if ( r < 0 ) {
        Format ( kMsgError, "Errors occured rotating logfile!", vl1 );
    } else if ( r > 0 ) {
        if ( !fBanner.empty() ) {
            va_list vl2;
            va_start(vl2, debug);
            Format ( kMsgInfo, fBanner.c_str(), vl2 ,debug);
            va_end(vl2);
        }
        Format ( kMsgOk, "Logfile rotated", vl1 ,debug);
        va_end(vl1);
    }
    // 0 == no need to rotate
    Format ( type, fmt, args ,debug);

//   TThread::UnLock();  // end of the asynchronous code section
}

void XrdDownloadManagerLog::Format ( MsgType_t type, const char *fmt, va_list args ,int debug) {

    char prefix[4];

    switch ( type ) {
    case kMsgOk:
        strcpy ( prefix, "O" );
        break;
    case kMsgWarning:
        strcpy ( prefix, "W" );
        break;
    case kMsgInfo:
        strcpy ( prefix, "I" );
        break;
    case kMsgError:
        strcpy ( prefix, "E" );
        break;
    case kMsgFatal:
        strcpy ( prefix, "F" );
        break;
    case kMsgDebug:
		sprintf( prefix, "D%d",debug );
        break;
    }
    time ( &fDatime );
    struct tm *timeinfo = localtime ( &fDatime );
    char buffer [80];
    strftime ( buffer,80,"%y%m%d %X",timeinfo );
    fprintf ( fLogFile, "[%s] xrddm-%s => ", buffer, prefix );
    vfprintf ( fLogFile, fmt, args );
    fputc ( '\n', fLogFile );
    fflush ( fLogFile );

}

void XrdDownloadManagerLog::SetDebug ( int debug ) {
    fDebug = debug;
}

void XrdDownloadManagerLog::Debug ( int debug,const char *fmt, ... ) {
    if ( fDebug >= debug ) {
        va_list args;
        va_start ( args, fmt );
        CheckRotateAndFormat ( kMsgDebug, fmt, args, debug );
        va_end ( args );
    }
}

void XrdDownloadManagerLog::Info ( const char *fmt, ... ) {
    va_list args;
    va_start ( args, fmt );
    CheckRotateAndFormat ( kMsgInfo, fmt, args );
    va_end ( args );
}

void XrdDownloadManagerLog::Ok ( const char *fmt, ... ) {
    va_list args;
    va_start ( args, fmt );
    CheckRotateAndFormat ( kMsgOk, fmt, args );
    va_end ( args );
}

void XrdDownloadManagerLog::Warning ( const char *fmt, ... ) {
    va_list args;
    va_start ( args, fmt );
    CheckRotateAndFormat ( kMsgWarning, fmt, args );
    va_end ( args );
}

void XrdDownloadManagerLog::Error ( const char *fmt, ... ) {
    va_list args;
    va_start ( args, fmt );
    CheckRotateAndFormat ( kMsgError, fmt, args );
    va_end ( args );
}

void XrdDownloadManagerLog::Fatal ( const char *fmt, ... ) {
    va_list args;
    va_start ( args, fmt );
    CheckRotateAndFormat ( kMsgFatal, fmt, args );
    va_end ( args );
}
